/**
 *  rotated_text.vala
 *
 *  Copyright (c) 2007 Marcelo Lira dos Santos <setanta@gmail.com>
 *                2007 INdT (Instituto Nokia de Technologia)
 *
 *  Author: Marcelo Lira dos Santos <setanta@gmail.com>
 *
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License as
 *  published by the Free Software Foundation; either version 2 of the
 *  License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 *  USA
 */

using GLib;
using Gtk;
using Pango;

public class RotatedTextDemo : GLib.Object
{
    const int RADIUS = 150;
    const int N_WORDS = 10;
    const string FONT = "Sans Bold 27";

    DrawingArea drawing_area;

    bool rotated_text_expose_event (Widget widget, Gdk.EventExpose event)
    {
        Renderer renderer;
        Matrix matrix;
        Context context;
        Pango.Layout layout;
        FontDescription desc;

        int width = widget.allocation.width;
        int height = widget.allocation.height;
        double device_radius;

        /* Get the default renderer for the screen, and set it up for drawing  */
        renderer = Gdk.PangoRenderer.get_default(widget.get_screen());
        ((Gdk.PangoRenderer) renderer).set_drawable (widget.window);
        ((Gdk.PangoRenderer) renderer).set_gc (widget.style.black_gc);

        /* Set up a transformation matrix so that the user space coordinates for
         * the centered square where we draw are [-RADIUS, RADIUS], [-RADIUS, RADIUS]
         * We first center, then change the scale */
        int min = (width < height) ? width : height;
        device_radius = min / 2.;
        matrix.translate(device_radius + (width - 2 * device_radius) / 2,
                         device_radius + (height - 2 * device_radius) / 2);
        matrix.scale (device_radius / RADIUS, device_radius / RADIUS);

        /* Create a PangoLayout, set the font and text */
        context = widget.create_pango_context();
        layout = new Pango.Layout(context);
        layout.set_text("Text", -1);
        desc = FontDescription.from_string(FONT);
        layout.set_font_description(desc);
        //How to do it in Vala: pango_font_description_free (desc);

        /* Draw the layout N_WORDS times in a circle */
        for (int i = 0; i < N_WORDS; i++)
        {
            Gdk.Color color;
            color.pixel = 0;
            Matrix rotated_matrix = matrix;
            int width, height;
            double angle = (360. * i) / N_WORDS;

            /* Gradient from red at angle == 60 to blue at angle == 300 */
            color.red = (ushort) (65535 * (1 + Math.cos ((angle - 60) * Math.PI / 180.)) / 2);
            color.green = (ushort) 0;
            color.blue  = (ushort) (65535 - color.red);

            ((Gdk.PangoRenderer) renderer).set_override_color(RenderPart.FOREGROUND, ref color);
            matrix.rotate(angle);
            context.set_matrix(ref rotated_matrix);

            /* Inform Pango to re-layout the text with the new transformation matrix */
            layout.context_changed();

            layout.get_size(ref width, ref height);
            //stdout.printf("width %d, height %d\n", width, height);
            renderer.draw_layout(layout, - width / 2, - RADIUS * 1024); // PANGO_SCALE = 1024
        }

        /* Clean up default renderer, since it is shared */
        ((Gdk.PangoRenderer) renderer).set_override_color(RenderPart.FOREGROUND, null);
        ((Gdk.PangoRenderer) renderer).set_drawable(null);
        ((Gdk.PangoRenderer) renderer).set_gc(null);

        /* free the objects we created */
        //g_object_unref (layout);
        //g_object_unref (context);

        return false;
    }

    public Window do_rotated_text ()
    {
        Window window = new Window(WindowType.TOPLEVEL);
        window.title = "Rotated Text";
        window.border_width = 10;
        window.set_default_size(2 * RADIUS, 2 * RADIUS);
        window.destroy += Gtk.main_quit;

        Gdk.Color white;
        white.pixel = (uint) 0;
        white.red = (ushort) 65535;
        white.green = (ushort) 65535;
        white.blue = (ushort) 65535;

        drawing_area = new DrawingArea();
        window.add(drawing_area);

        drawing_area.modify_bg(StateType.NORMAL, ref white);
        drawing_area.expose_event += rotated_text_expose_event;

        return window;
    }

    static int main (string[] args) {
        Gtk.init(out args);

        RotatedTextDemo rtd = new RotatedTextDemo();

        var win = rtd.do_rotated_text();
        try {
            win.set_default_icon_from_file("v-icon.png");
        } catch (GLib.Error error) {
            critical(error.message);
        }
        win.show_all();

        Gtk.main();

        return 0;
    }
}

